<?php

namespace App\Services;

use App\Models\Setting;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage;

class SettingService
{
    const CACHE_KEY  = 'settings';
    const EXPIRED_AT = 60; // 60 minutes

    /**
     * 加載配置
     *
     * @return array
     */
    public function load()
    {
        $settings = [];

        Setting::get(['type', 'name', 'value'])->each(function ($item, $key) use (&$settings) {
            data_set($settings, strtolower("{$item['type']}.{$item['name']}"), $item['value']);
        });

        return $settings;
    }

    /**
     * 獲取所有配置
     *
     * @param string $type
     * @return array
     */
    public function all($type = '')
    {
        return Setting::when($type, function ($query, $type) {
            $query->where('type', $type);
        })
            ->get()
            ->all();
    }

    /**
     * 獲取所有配置類型
     *
     * @return array
     */
    public function types()
    {
        return Setting::groupBy('type')
            ->get(['type'])
            ->pluck('type')
            ->all();
    }

    /**
     * 獲取配置值
     *
     * @param string $name
     * @param string $default
     * @return mixed
     */
    public function get($name = '', $default = '')
    {
        $settings = Cache::remember(self::CACHE_KEY, now()->addMinute(self::EXPIRED_AT), function () {
            return $this->load();
        });

        $name = strtolower($name);
        $name = trim($name, '.');

        if (!$name) {
            return $settings;
        }

        return Arr::get($settings, $name, $default);
    }

    /**
     * 新增配置
     *
     * @param array $attributes
     * @return boolean
     */
    public function store($attributes = [])
    {
        return Setting::updateOrCreate([
            'type' => $attributes['type'],
            'name' => $attributes['name'],
        ], [
            'value'       => $attributes['value'],
            'description' => $attributes['description'],
        ]);
    }

    /**
     * 更新配置
     *
     * @param int   $id
     * @param array $attributes
     * @return boolean
     */
    public function update($id, $attributes = [])
    {
        return Setting::find($id)->update([
            'value'       => $attributes['value'] ?? '',
            'description' => $attributes['description'] ?? '',
        ]);
    }

    /**
     * 檢測配置是否存在
     *
     * @param string $type
     * @param string $name
     * @return int
     */
    public function exists($type, $name)
    {
        return Setting::where('type', $type)
            ->where('name', $name)
            ->count();
    }

    /**
     * 獲取配置
     *
     * @param int $id
     * @return array
     */
    public function row($id)
    {
        return Setting::find($id)->toArray();
    }

    /**
     * 刪除配置
     *
     * @param string/array $id
     * @return boolean
     */
    public function delete($id = '')
    {
        if (!is_array($id) && !is_numeric($id)) {
            return false;
        }
        if (!Setting::destroy($id)) {
            return false;
        }
        return true;
    }

    /**
     * 更新至緩存文件
     *
     * @param boolean $force
     * @return void
     */
    public function storage($force = false)
    {
        $storage  = Storage::disk('local');
        $filePath = 'setting.php';
        $path     = storage_path('app/' . $filePath);

        // 生成緩存
        if (!$force && $storage->exists($filePath)) {
            return $path;
        }

        $contents = '<?php return ' . var_export($this->load(), 1) . ';';
        $storage->put($filePath, $contents);

        return $path;
    }
}
